﻿using System;
using System.ComponentModel.Design;
using System.IO;
using EnvDTE;
using EnvDTE80;
using Microsoft.VisualStudio.Shell;
using QuickShare.Vsix.SqlList.Commons;
using QuickShare.Vsix.SqlList.Forms;
using Task = System.Threading.Tasks.Task;

namespace QuickShare.Vsix.SqlList.Commands
{
    /// <summary>
    /// Command handler
    /// </summary>
    internal sealed class CommandInit
    {
        private DTE2 dte2;
        /// <summary>
        /// Command ID.
        /// </summary>
        public const int CommandId = 0x0100;

        /// <summary>
        /// Command menu group (command set GUID).
        /// </summary>
        public static readonly Guid CommandSet = new Guid("7ba8dde6-ac6b-47dd-9db8-b57a2c9e34a5");

        /// <summary>
        /// VS Package that provides this command, not null.
        /// </summary>
        private readonly AsyncPackage package;

        /// <summary>
        /// Initializes a new instance of the <see cref="CommandInit"/> class.
        /// Adds our command handlers for menu (commands must exist in the command table file)
        /// </summary>
        /// <param name="package">Owner package, not null.</param>
        /// <param name="commandService">Command service to add command to, not null.</param>
        private CommandInit(AsyncPackage package, OleMenuCommandService commandService)
        {
            this.package = package ?? throw new ArgumentNullException(nameof(package));
            commandService = commandService ?? throw new ArgumentNullException(nameof(commandService));

            var menuCommandID = new CommandID(CommandSet, CommandId);
            var menuItem = new OleMenuCommand(this.Execute, null, OnBeforeQueryStatusDynamicItem, menuCommandID);
            commandService.AddCommand(menuItem);
            dte2 = (DTE2)this.ServiceProvider.GetServiceAsync(typeof(DTE)).Result;
        }

        /// <summary>
        /// This function is the callback used to execute the command when the menu item is clicked.
        /// See the constructor to see how the menu item is associated with this function using
        /// OleMenuCommandService service and MenuCommand class.
        /// </summary>
        /// <param name="sender">Event sender.</param>
        /// <param name="e">Event args.</param>
        private async void Execute(object sender, EventArgs e)
        {
            await ThreadHelper.JoinableTaskFactory.SwitchToMainThreadAsync();
            await dte2.WriteInConsole("初始化SqlList插件完成");
            var project =await dte2.GetCurrentProject();
            if(project == null)
            {
                this.package.ShowMessage("请选择项目进行配置", "配置发布目录");
                return;
            }
            
            var solutionPath = Path.GetDirectoryName(dte2.Solution.FullName);
            var projectName = Path.GetFileNameWithoutExtension(project.FullName);
            var sqllistdir = DTEHelper.TryCreateSqlListDir(solutionPath, projectName);
            Commons.Command.LogDir = sqllistdir;
            var path = Path.Combine(sqllistdir, DTEHelper.CONFIG_FILE);
            var frmDeploy = new FrmDeployInfos(projectName, path, null);
            var da = frmDeploy.ShowDialog();
            if(da != System.Windows.Forms.DialogResult.OK)
            {
                return;
            }
            var val = frmDeploy.Value;
            await dte2.WriteInConsole($"配置 {project.Name} 发布目录：{val.Path}，静态资源扩展列表：{val.StaticFileExts}");
        }
        private void OnBeforeQueryStatusDynamicItem(object sender, EventArgs args)
        {
            OleMenuCommand menuCommand = (OleMenuCommand)sender;
            if(menuCommand == null)
            {
                return;
            }
            menuCommand.Enabled = false;
            menuCommand.Visible = false;
        }

        /// <summary>
        /// Gets the instance of the command.
        /// </summary>
        public static CommandInit Instance
        {
            get;
            private set;
        }

        /// <summary>
        /// Gets the service provider from the owner package.
        /// </summary>
        private Microsoft.VisualStudio.Shell.IAsyncServiceProvider ServiceProvider
        {
            get
            {
                return this.package;
            }
        }

        /// <summary>
        /// Initializes the singleton instance of the command.
        /// </summary>
        /// <param name="package">Owner package, not null.</param>
        public static async Task InitializeAsync(AsyncPackage package)
        {
            // Switch to the main thread - the call to AddCommand in CommandInit's constructor requires
            // the UI thread.
            await ThreadHelper.JoinableTaskFactory.SwitchToMainThreadAsync(package.DisposalToken);

            OleMenuCommandService commandService = await package.GetServiceAsync(typeof(IMenuCommandService)) as OleMenuCommandService;
            Instance = new CommandInit(package, commandService);
        }
    }
}
